package cn.csc.module.pay.controller.app.jzb;

import cn.csc.framework.common.pojo.CommonResult;
import cn.csc.framework.common.pojo.PageResult;
import cn.csc.framework.common.util.number.ObjectNumberUtils;
import cn.csc.framework.jzb.core.JzbClient;
import cn.csc.framework.jzb.vo.JzbResponse;
import cn.csc.framework.pay.core.client.PayCommonResult;
import cn.csc.framework.security.core.annotations.PreAuthenticated;
import cn.csc.framework.tenant.core.context.TenantContextHolder;
import cn.csc.module.pay.api.card.dto.PayCardRespDTO;
import cn.csc.module.pay.api.refund.dto.PayRefundCreateReqDTO;
import cn.csc.module.pay.controller.admin.bank.vo.PayBankCreateReqVO;
import cn.csc.module.pay.controller.admin.bank.vo.PayBankRespApiVO;
import cn.csc.module.pay.controller.admin.card.vo.PayCardCreateReqVO;
import cn.csc.module.pay.controller.admin.fund.vo.PayFundCreateReqVO;
import cn.csc.module.pay.controller.admin.fund.vo.PayFundPageReqVO;
import cn.csc.module.pay.controller.admin.fund.vo.PayFundRespVO;
import cn.csc.module.pay.controller.admin.funddetails.vo.PayFundDetailsPageReqVO;
import cn.csc.module.pay.controller.admin.funddetails.vo.PayFundDetailsRespVO;
import cn.csc.module.pay.controller.admin.rate.vo.PayJzbRateRespVO;
import cn.csc.module.pay.controller.app.jzb.vo.*;
import cn.csc.module.pay.controller.app.order.vo.AppPayOrderSubmitRespVO;
import cn.csc.module.pay.convert.bank.PayBankConvert;
import cn.csc.module.pay.convert.card.PayCardConvert;
import cn.csc.module.pay.convert.fund.PayFundConvert;
import cn.csc.module.pay.convert.funddetails.PayFundDetailsConvert;
import cn.csc.module.pay.convert.order.PayOrderConvert;
import cn.csc.module.pay.convert.rate.PayJzbRateConvert;
import cn.csc.module.pay.dal.dataobject.bank.PayBankDO;
import cn.csc.module.pay.dal.dataobject.fund.PayFundDO;
import cn.csc.module.pay.dal.dataobject.funddetails.PayFundDetailsDO;
import cn.csc.module.pay.dal.dataobject.merchant.PayAppDO;
import cn.csc.module.pay.dal.dataobject.rate.PayJzbRateDO;
import cn.csc.module.pay.enums.ErrorCodeConstants;
import cn.csc.module.pay.service.bank.PayBankService;
import cn.csc.module.pay.service.card.PayCardService;
import cn.csc.module.pay.service.drawcash.PayDrawCashService;
import cn.csc.module.pay.service.fund.PayFundService;
import cn.csc.module.pay.service.funddetails.PayFundDetailsService;
import cn.csc.module.pay.service.jzborder.JzbOrderService;
import cn.csc.module.pay.service.merchant.PayAppService;
import cn.csc.module.pay.service.rate.PayJzbRateService;
import cn.csc.module.pay.util.SignUtils;
import com.alibaba.fastjson.JSONObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.math.BigInteger;

import static cn.csc.framework.common.pojo.CommonResult.error;
import static cn.csc.framework.common.pojo.CommonResult.success;
import static cn.csc.module.pay.enums.DictTypeConstants.PAY_APP_SECRET;

/**
 * 见证宝业务
 *
 * @author liuchuang
 * @version 1.0
 * @date 2023/5/5 15:03
 * @modify
 */
@Api(tags = "用户 APP - 见证宝业务")
@RestController
@RequestMapping("/pay/jzb")
@Validated
@Slf4j
@Setter
public class AppJzbController {
    @Autowired
    private JzbClient jzbClient;

    @Autowired
    private PayFundService payFundService;
    @Autowired
    private PayFundDetailsService fundDetailsService;
    @Autowired
    private PayCardService payCardService;
    @Autowired
    private PayBankService payBankService;
    @Autowired
    private JzbOrderService jzbOrderService;
    @Autowired
    private PayDrawCashService payDrawCashService;

    @Autowired
    private PayJzbRateService payJzbRateService;

    @Resource
    private PayAppService appService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    //会员开立相关 yequnli
    @PostMapping("/autonymOpenCustAcctId")
    @ApiOperation(value = "会员子账户开立")
    @PreAuthenticated
    public CommonResult<JzbResponse> autonymOpenCustAcctId(@Validated @RequestBody AutonymOpenCustAcctIdReqVO reqVO) {
        log.info(reqVO + "---reqVO");
        JSONObject jsonObject = new JSONObject();
        //功能标识:1:开户 3:销户 4: 为存量见证子帐号申请智能收款子账号
        jsonObject.put("FunctionFlag", "1");
        //交易网会员代码:平台端的用户ID，需要保证唯一性，可数字字母混合，如HY_120，若需要开通智能收款要求后6位是数字，该6位数字为智能收款账号后6位，因账号前几位固定故后6位不能重复。
        jsonObject.put("TranNetMemberCode", reqVO.getAppUserId());
        //客户真实姓名
        jsonObject.put("MemberName", reqVO.getMemberName());
        //会员证件类型
        jsonObject.put("MemberGlobalType", reqVO.getMemberGlobalType());
        //会员证件号码
        jsonObject.put("MemberGlobalId", reqVO.getMemberGlobalId());
        //会员属性: SH-商户子账户(默认) 00-普通子账户
        jsonObject.put("MemberProperty", "SH");

        //手机号码测试送11个1
        jsonObject.put("Mobile", reqVO.getMobile());
        //邮箱
        jsonObject.put("Email", reqVO.getEmail());
        //个体工商户标志1：是 2：否(个人必输)
        jsonObject.put("IndivBusinessFlag", reqVO.getIndivBusinessFlag());
        if (1 == reqVO.getIndivBusinessFlag()) {//个体户
            //公司名称个体工商户必输
            jsonObject.put("CompanyName", reqVO.getCompanyName());
            //公司证件类型个体工商户必输73-统一社会信用代码证号"
            jsonObject.put("CompanyGlobalType", reqVO.getCompanyGlobalType());
            //公司证件号码个体工商户必输
            jsonObject.put("CompanyGlobalId", reqVO.getCompanyGlobalId());
        }
        //店铺id个体工商户必输
        jsonObject.put("ShopId", reqVO.getShopId());
        //店铺名称个体工商户必输
        jsonObject.put("ShopName", reqVO.getShopName());
        //法人标志,1-是
        jsonObject.put("RepFlag", reqVO.getRepFlag());
        //法人名称,个体工商户必输
        jsonObject.put("ReprName", reqVO.getReprName());
        //法人证件类型,个体工商户必输
        jsonObject.put("ReprGlobalType", reqVO.getReprGlobalType());
        //法人证件号码,个体工商户必输
        jsonObject.put("ReprGlobalId", reqVO.getReprGlobalId());
        log.info("[autonymOpenCustAcctId]jsonObject: {}" , jsonObject);
        //调用业务接口
        JzbResponse jzb = jzbClient.send(jsonObject, "KFEJZB6248", "/V1.0/AutonymOpenCustAcctId");
        log.info("[autonymOpenCustAcctId]response: {}" , jzb);
        if (jzb.isSuccess()) {
            JSONObject data = jzb.getData().getJSONObject("Data");
            //插入一条数据到pay_card
            PayCardCreateReqVO payCardCreateReqVO = PayCardConvert.INSTANCE.convert1(reqVO);
            payCardCreateReqVO.setAppUserId(reqVO.getAppUserId());
            Long l = payCardService.createCard(payCardCreateReqVO);
            log.info("[autonymOpenCustAcctId]: {}" , l);
            //插入一条数据到pay_fund
            PayFundCreateReqVO payFundCreateReqVO = new PayFundCreateReqVO();
            payFundCreateReqVO.setJzbCode(String.valueOf(data.get("SubAcctNo")));
            payFundCreateReqVO.setAppUserId(reqVO.getAppUserId());
            payFundCreateReqVO.setMerchantId(reqVO.getMerchantId());
            payFundCreateReqVO.setFundType(reqVO.getIndivBusinessFlag());
            log.info("[autonymOpenCustAcctId]payFundCreateReqVO: {}" , payFundCreateReqVO);
            payFundService.createFund(payFundCreateReqVO);
            return success(jzb);

        }
        String extendData = jzb.getData().get("ExtendData").toString();
        log.info("jzb--extendData---" + extendData);
        JSONObject jsobjerror = JSONObject.parseObject(extendData);
        String txnReturnMsg = String.valueOf(jsobjerror.get("TxnReturnMsg"));
        log.info("jzb--txnReturnMsg---" + txnReturnMsg);
        return error(ErrorCodeConstants.AUTONYM_OPEN_CUST_ACCTID_ERR, jzb);
    }

    @PostMapping("/bindUnionPayWithCheckCorp")
    @ApiOperation(value = "会员绑定提现账户-银联鉴权-个人")
    @PreAuthenticated
    public CommonResult<JzbResponse> bindUnionPayWithCheckCorp(@Validated @RequestBody BindUnionPayWithCheckCorpReqVO reqVO) {
        JSONObject jsonObject = new JSONObject();
        PayFundPageReqVO payFundPageReqVO = new PayFundPageReqVO();
        payFundPageReqVO.setAppUserId(reqVO.getAppUserId());
        payFundPageReqVO.setMerchantId(reqVO.getMerchantId());
        PayFundDO payFundDO = payFundService.getJzbCode(payFundPageReqVO);
        //子账户账号 5798000000016154
        jsonObject.put("SubAcctNo", payFundDO.getJzbCode());
        //交易网会员代码
        jsonObject.put("TranNetMemberCode", reqVO.getAppUserId());
        //会员名称
        jsonObject.put("MemberName", reqVO.getMemberName());
        //会员证件类型:1为纯个人或者个体工商户客户,3、5为纯个人，证件类型仅支持1/3/5。
        jsonObject.put("MemberGlobalType", reqVO.getMemberGlobalType());
        //会员证件号码
        jsonObject.put("MemberGlobalId", reqVO.getMemberGlobalId());
        //会员账号:提现的银行卡
        jsonObject.put("MemberAcctNo", reqVO.getMemberAcctNo());
        //银行类型:1：本行 2：他行
        jsonObject.put("BankType", reqVO.getBankType());
        //开户行名称
        jsonObject.put("AcctOpenBranchName", reqVO.getAcctOpenBranchName());
        //大小额行号：大小额行号和超级网银行号两者二选一必填。
        jsonObject.put("CnapsBranchId", reqVO.getCnapsBranchId());
        //手机号码
        jsonObject.put("Mobile", reqVO.getMobile());

        //是否个体工商户：1：是 2：否
        jsonObject.put("IndivBusinessFlag", reqVO.getIndivBusinessFlag());
        //公司名称
        jsonObject.put("CompanyName", reqVO.getCompanyName());
        //公司证件类型：证件类型仅支持73-统一社会信用代码、68-营业执照 、52-组织机构代码证
        jsonObject.put("CompanyGlobalType", reqVO.getCompanyGlobalType());
        //公司证件号码
        jsonObject.put("CompanyGlobalId", reqVO.getCompanyGlobalId());
        //店铺id
        jsonObject.put("ShopId", reqVO.getShopId());
        //店铺名称
        jsonObject.put("ShopName", reqVO.getShopName());

        //会员名称是否是法人：1-是  2-否（个体工商户必输）
        jsonObject.put("RepFlag", reqVO.getRepFlag());
        //法人名称
        jsonObject.put("ReprName", reqVO.getReprName());
        //法人证件类型
        jsonObject.put("ReprGlobalType", reqVO.getReprGlobalType());
        //法人证件号码
        jsonObject.put("ReprGlobalId", reqVO.getReprGlobalId());

        //调用业务接口
        JzbResponse jzb = jzbClient.send(jsonObject, "KFEJZB6238", "/V1.0/BindUnionPayWithCheckCorp");
        log.info("[bindUnionPayWithCheckCorp]response: {}" , jzb);
        if (jzb.isSuccess()) {
            JSONObject jsobj = jzb.getData();
            PayBankCreateReqVO createReqVO = PayBankConvert.INSTANCE.convert(reqVO);
            createReqVO.setBindBankType(new BigInteger("1"));
            payBankService.createBank(createReqVO);
            return success(jzb);
        }

        return error(ErrorCodeConstants.CHECK_AMOUNT_WITH_P_PARAMS_ERR, jzb);
    }

    @PostMapping("/checkMsgCodeWithCorp")
    @ApiOperation(value = "会员绑定提现账户-银联鉴权-个人")
    @PreAuthenticated
    public CommonResult<JzbResponse> checkMsgCodeWithCorp(@Validated @RequestBody CheckMsgCodeWithCorpReqVO reqVO) {
        JSONObject jsonObject = new JSONObject();
        PayFundPageReqVO payFundPageReqVO = new PayFundPageReqVO();
        payFundPageReqVO.setAppUserId(reqVO.getAppUserId());
        payFundPageReqVO.setMerchantId(reqVO.getMerchantId());
        PayFundDO payFundDO = payFundService.getJzbCode(payFundPageReqVO);
        if (payFundDO == null) {
            return error(-1, "参数不能为空！");
        }
        jsonObject.put("SubAcctNo", payFundDO.getJzbCode());
        jsonObject.put("TranNetMemberCode", reqVO.getAppUserId());
        jsonObject.put("MemberAcctNo", reqVO.getMemberAcctNo());
        jsonObject.put("MessageCheckCode", reqVO.getMessageCheckCode());

        //调用业务接口
        JzbResponse jzb = jzbClient.send(jsonObject, "KFEJZB6239", "/V1.0/CheckMsgCodeWithCorp");
        log.info("[checkMsgCodeWithCorp]response: {}" , jzb);
        if (jzb.isSuccess()) {
            JSONObject jsobj = jzb.getData();
            //插入一条数据到pay_bank
            PayBankDO payBankDO = new PayBankDO();
            payBankDO.setState(1);
            payBankDO.setAppUserId(reqVO.getAppUserId());
            payBankDO.setMerchantId(reqVO.getMerchantId().longValue());
            payBankService.updateState(payBankDO);
            return success(jzb);
        }
        return error(ErrorCodeConstants.CHECK_AMOUNT_WITH_P_JZB_ERR, jzb);
    }

    @PostMapping("/bindSmallAmountWithCheckCorp")
    @ApiOperation(value = "会员绑定提现账户-银联鉴权-企业")
    @PreAuthenticated
    public CommonResult<JzbResponse> bindSmallAmountWithCheckCorp(@Validated @RequestBody BindSmallAmountWithCheckCorpReqVO reqVO) {
        JSONObject jsonObject = new JSONObject();
        PayFundPageReqVO payFundPageReqVO = new PayFundPageReqVO();
        payFundPageReqVO.setAppUserId(reqVO.getAppUserId());
        payFundPageReqVO.setMerchantId(reqVO.getMerchantId());
        PayFundDO payFundDO = payFundService.getJzbCode(payFundPageReqVO);

        jsonObject.put("SubAcctNo", payFundDO.getJzbCode());
        jsonObject.put("TranNetMemberCode", reqVO.getAppUserId());

        jsonObject.put("MemberName", reqVO.getMemberName());
        jsonObject.put("MemberGlobalType", reqVO.getMemberGlobalType());
        jsonObject.put("MemberGlobalId", reqVO.getMemberGlobalId());
        jsonObject.put("MemberAcctNo", reqVO.getMemberAcctNo());
        jsonObject.put("BankType", reqVO.getBankType());
        jsonObject.put("AcctOpenBranchName", reqVO.getAcctOpenBranchName());
        jsonObject.put("Mobile", reqVO.getMobile());
        jsonObject.put("CnapsBranchId", reqVO.getCnapsBranchId());
        jsonObject.put("IndivBusinessFlag", reqVO.getIndivBusinessFlag());
        jsonObject.put("CompanyName", reqVO.getCompanyName());
        jsonObject.put("CompanyGlobalType", reqVO.getCompanyGlobalType());
        jsonObject.put("CompanyGlobalId", reqVO.getCompanyGlobalId());
        jsonObject.put("ShopId", reqVO.getShopId());
        jsonObject.put("ShopName", reqVO.getShopName());

        jsonObject.put("AgencyClientFlag", reqVO.getAgencyClientFlag());
        jsonObject.put("AgencyClientName", reqVO.getAgencyClientName());
        jsonObject.put("AgencyClientGlobalType", reqVO.getAgencyClientGlobalType());
        jsonObject.put("AgencyClientGlobalId", reqVO.getAgencyClientGlobalId());
        jsonObject.put("AgencyClientMobile", reqVO.getAgencyClientMobile());

        jsonObject.put("RepFlag", reqVO.getRepFlag());
        jsonObject.put("ReprName", reqVO.getReprName());
        jsonObject.put("ReprGlobalType", reqVO.getReprGlobalType());
        jsonObject.put("ReprGlobalId", reqVO.getReprGlobalId());
        //调用业务接口
        log.info("[bindSmallAmountWithCheckCorp]jsonObject: {}" , jsonObject);
        JzbResponse jzb = jzbClient.send(jsonObject, "KFEJZB6240", "/V1.0/BindSmallAmountWithCheckCorp", reqVO.getCnsmrSeqNo());
        log.info("[bindSmallAmountWithCheckCorp]response: {}" , jzb);
        if (jzb.isSuccess()) {
            PayBankCreateReqVO createReqVO = PayBankConvert.INSTANCE.convert(reqVO);
            createReqVO.setBindBankType(new BigInteger("2"));
            payBankService.createBank(createReqVO);
            return success(jzb);
        }
        return error(ErrorCodeConstants.BIND_SMALL_AMOUNT_WITH_CHECK_CORP_ERR, jzb);
    }

    /**
     * 此接口是小额转账鉴权【6240】的配套接口，用于验证鉴权是否成功
     * 与会员绑定提现账户小额鉴权-校验法人【6240】一起搭配使用，回填金额应为两位小数，客户回填的金额平台应对格式进行校验，超过两位小数或者大于0.5的应给客户提示，如格式不正确或大于随机转入金额等
     *
     * @param reqVO 小额鉴权回填金额参数
     * @return
     */
    @PostMapping("/checkAmountWithCorp")
    @ApiOperation(value = "会员绑定提现账户-小额鉴权回填金额--企业")
    @PreAuthenticated
    public CommonResult<JzbResponse> checkAmountWithCorp(@RequestBody CheckAmountWithCorpReqVO reqVO) {
        JSONObject jsonObject = new JSONObject();
        //资金汇总账号
        PayFundPageReqVO payFundPageReqVO = new PayFundPageReqVO();
        payFundPageReqVO.setAppUserId(reqVO.getAppUserId());
        payFundPageReqVO.setMerchantId(reqVO.getMerchantId());
        PayFundDO payFundDO = payFundService.getJzbCode(payFundPageReqVO);
        if (payFundDO == null) {
            return error(ErrorCodeConstants.CHECK_AMOUNT_WITH_CORP_PARAMS_ERR);
        }
        jsonObject.put("SubAcctNo", payFundDO.getJzbCode());
        jsonObject.put("TranNetMemberCode", reqVO.getAppUserId());

        jsonObject.put("TakeCashAcctNo", reqVO.getTakeCashAcctNo());
        jsonObject.put("AuthAmt", reqVO.getAuthAmt());
        jsonObject.put("OrderNo", reqVO.getOrderNo());
        jsonObject.put("Ccy", "RMB");

        //调用业务接口, 外部传入见证宝交易流水号
        JzbResponse jzb = jzbClient.send(jsonObject, "KFEJZB6241", "/V1.0/CheckAmountWithCorp", reqVO.getCnsmrSeqNo());
        log.info("[checkAmountWithCorp]response: {}" , jzb);
        if (jzb.isSuccess()) {
            //修改一条数据到pay_bank
            PayBankDO payBankDO = new PayBankDO();
            payBankDO.setState(1);
            payBankDO.setAppUserId(reqVO.getAppUserId());
            payBankDO.setMerchantId(reqVO.getMerchantId().longValue());
            payBankService.updateState(payBankDO);
            return success(jzb);
        }
        return error(ErrorCodeConstants.CHECK_AMOUNT_WITH_CORP_JZB_ERR, jzb);
    }

    @PostMapping("/memberBindQuery")
    @ApiOperation(value = "会员绑定信息查询")
    @PreAuthenticated
    public CommonResult<JzbResponse> memberBindQuery(@RequestBody MemberBindQueryReqVO reqVO) {
        JSONObject jsonObject = new JSONObject();
        PayFundPageReqVO payFundPageReqVO = new PayFundPageReqVO();
        payFundPageReqVO.setAppUserId(reqVO.getAppUserId());
        payFundPageReqVO.setMerchantId(reqVO.getMerchantId());
        PayFundDO payFundDO = payFundService.getJzbCode(payFundPageReqVO);
        if (payFundDO == null) {
            return error(-1, "参数不能为空！");
        }
        //查询标志:1：全部会员 2：单个会员
        jsonObject.put("QueryFlag", "2");

        //见证子账户的账号:若QueryFlag为2时必输
        jsonObject.put("SubAcctNo", payFundPageReqVO.getJzbCode());
        //页码:起始值为1，每次最多返回20条记录，第二页返回的记录数为第21至40条记录，第三页为41至60条记录，顺序均按照建立时间的先后
        jsonObject.put("PageNum", reqVO.getPageNum());

        jsonObject.put("ReservedMsg", "");

        //调用业务接口
        JzbResponse jzb = jzbClient.send(jsonObject, "KFEJZB6098", "/V1.0/MemberBindQuery");
        log.info("[memberBindQuery]response: {}" , jzb);
        if (jzb.isSuccess()) {
            JSONObject jsobj = jzb.getData();
            System.out.println(jsobj.toString());

        }
        return error(ErrorCodeConstants.CHECK_AMOUNT_WITH_BIND_JZB_ERR, jzb);
    }

    @PostMapping("/unbindRelateAcct")
    @ApiOperation(value = "会员解绑提现账户")
    @PreAuthenticated
    public CommonResult<JzbResponse> unbindRelateAcct(@Validated @RequestBody UnbindRelateAcctReqVO reqVO) {
        JSONObject jsonObject = new JSONObject();
        PayFundPageReqVO payFundPageReqVO = new PayFundPageReqVO();
        payFundPageReqVO.setAppUserId(reqVO.getAppUserId());
        payFundPageReqVO.setMerchantId(reqVO.getMerchantId());
        PayFundDO payFundDO = payFundService.getJzbCode(payFundPageReqVO);
        if (payFundDO == null) {
            return error(-1, "参数不能为空！");
        }
        //功能标志: 1：解绑
        jsonObject.put("FunctionFlag", "1");
        //交易网会员代码:若需要把一个待绑定账户关联到两个会员名下，此字段可上送两个会员的交易网代码，并且须用“|::|”(右侧)进行分隔。如:99998|::|99996
        jsonObject.put("TranNetMemberCode", reqVO.getAppUserId());
        //若需要把一个待绑定账户关联到两个会员名下，此字段可上送两个会员的子账户账号，并且须用“|::|”(右侧)进行分隔。如:3144000000001089|::|3144000000001169
        //注意，上面的会员代码的位置和子账户的位置需要一致，即前一个的会员代码对应的的子账户需在第一位
        jsonObject.put("SubAcctNo", payFundDO.getJzbCode());
        jsonObject.put("MemberAcctNo", reqVO.getMemberAcctNo());

        //调用业务接口
        JzbResponse jzb = jzbClient.send(jsonObject, "KFEJZB6065", "/V1.0/UnbindRelateAcct");
        log.info("[unbindRelateAcct]response: {}" , jzb);
        if (jzb.isSuccess()) {
            //修改一条数据到pay_bank
            PayBankDO payBankDO = new PayBankDO();
            payBankDO.setMemberAcctNo(reqVO.getMemberAcctNo());
            payBankDO.setState(2);
            payBankDO.setMerchantId(Long.parseLong(reqVO.getMerchantId().toString()));
            payBankDO.setAppUserId(reqVO.getAppUserId());
            payBankService.updateStateById(payBankDO);
            return success(jzb);
        }
        return error(ErrorCodeConstants.CHECK_AMOUNT_WITH_UNBIND_JZB_ERR, jzb);
    }

    //-------------------------------------------

    //充值体现相关 zengtieshu

    @PreAuthenticated
    @PostMapping("/submit")
    @ApiOperation(value = "提交支付订单")
    public CommonResult<AppPayOrderSubmitRespVO> submitPayOrder() {
        JSONObject jsonObject = new JSONObject();

        String seq = ObjectNumberUtils.getOrder("");
        //会员子账号
        jsonObject.put("MemberSubAcctNo", "5655000000001036");
        //交易网会员代码
        jsonObject.put("TranWebMemberId", "HD_001");
        //会员充值金额
        jsonObject.put("MemberFillAmt", "0.1");
        //手续费金额
        jsonObject.put("Commission", "0.0");
        //币种
        jsonObject.put("Ccy", "RMB");
        //支付渠道类型0001-微信 0002-支付宝 0003-京东支付0004-百度支付//0005-快捷通支付//0006-裕福支付//0007-银联商务分期0008-拉卡拉支付0009-平安付0010-QQ钱包0011-通联
        // 0012-银联商务0013-银联0014-苏宁支付0015-乐刷支付0016-中金支付0017-合利宝0018-易宝支付0019-招行一网通0020-小米支付0021-合众支付0022-和包支付/0023-翼支付0024-交通银行0025-建设银行0026-宝付0027-工商银行0028-连连支付0029-钱袋宝

        jsonObject.put("PayChannelType", "0001");

        //支付渠道所分配的商户号：即市场在第三方支付渠道的商户号
        jsonObject.put("PayChannelAssignMerNo", "1");
        //支付渠道交易流水号：即上送给第三方支付渠道的支付交易的流水号或订单号
        jsonObject.put("PayChannelTranSeqNo", seq);
        //电商见证宝订单号：市场自行拟定，须保证单个市场下全局唯一
        jsonObject.put("EjzbOrderNo", seq);

        //电商见证宝订单内容
        jsonObject.put("EjzbOrderContent", "");
        //备注
        jsonObject.put("Remark", "0");
        //保留域1
        jsonObject.put("ReservedMsgOne", "1");
        //保留域2
        jsonObject.put("ReservedMsgTwo", "2");
        //保留域3
        jsonObject.put("ReservedMsgThree", "3");

        JzbResponse jzb = jzbClient.send(jsonObject, "KFEJZB6129", "/V1.0/MemberRechargeThirdPay");
        log.info("[submitPayOrder]response: {}" , jzb);
        if (jzb.isSuccess()) {
            JSONObject jsobj = jzb.getData();
            System.out.println(jsobj.toString());
        }
        return success(PayOrderConvert.INSTANCE.convert3(null));
    }


    //-------------------------------------------


    //查询相关 liuchuang
    @PreAuthenticated  //登录的用户才允许访问
    @PostMapping("/singleTransactionStatusQuery")
    @ApiOperation(value = "查询银行单笔交易状态")
    public CommonResult<JzbResponse> singleTransactionStatusQuery(@RequestBody SingleTransactionStatusReqVO reqVO) {
        JSONObject jsonObject = new JSONObject();
        //功能标识: 2：会员间交易 3：提现 4：充值 5：订单分账(6801) 6：在途充值分账
        jsonObject.put("FunctionFlag", reqVO.getFunctionFlag());

        //交易网流水号:提现，充值或会员交易请求时的CnsmrSeqNo值,6216分账时请求时的SubOrderBussSeqNo
        jsonObject.put("TranNetSeqNo", reqVO.getTranNetSeqNo());

        //见证子账户的账号(未启用)
        jsonObject.put("SubAcctNo", reqVO.getSubAcctNo());
        //交易日期:格式：20181201(未启用)
        jsonObject.put("TranDate", reqVO.getTranDate());
        //保留域
        jsonObject.put("ReservedMsg", "查询成功");

        JzbResponse response = jzbClient.send(jsonObject, "KFEJZB6110", "/V1.0/SingleTransactionStatusQuery");
        log.info("KFEJZB6110(查询银行单笔交易状态)调用返回：{}", response.getData());
        if (response.isSuccess()) {
            return success(response);
        }
        return error(ErrorCodeConstants.SINGLE_TRANSACTION_STATUS_QUERY_ERR, response);
    }



    @PostMapping("/queryCustAcctIdByThirdCustId")
    @ApiOperation(value = "根据会员代码查询会员子账号")  // 返回见证子账户的账号
    @PreAuthenticated
    public CommonResult<JzbResponse> queryCustAcctIdByThirdCustId(@RequestBody QueryCustAcctIdByThirdCustIdReqVO reqVO) {
        JSONObject jsonObject = new JSONObject();

        //交易网会员代码
        jsonObject.put("TranNetMemberCode", reqVO.getTranNetMemberCode());

        //保留域
        jsonObject.put("ReservedMsg", "查询成功");

        JzbResponse response = jzbClient.send(jsonObject, "KFEJZB6092", "/V1.0/QueryCustAcctIdByThirdCustId");
        log.info("KFEJZB6092(根据会员代码查询会员子账号)调用返回：{}", response.getData());
        if (response.isSuccess()) {
            return success(response);
        }
        return error(ErrorCodeConstants.QUERY_CUST_ACCTID_BYTHIRDCUSTID_ERR, response);
    }

    @PostMapping("/queryCustAcctId")
    @ApiOperation(value = "根据会员代码查询会员子账号")  //返回见证子账户的账号、余额信息、冻结金额
    @PreAuthenticated
    public CommonResult<JzbResponse> queryCustAcctId(@RequestBody QueryCustAcctIdByThirdCustIdReqVO reqVO) {
        JSONObject jsonObject = new JSONObject();

        //交易网会员代码
        jsonObject.put("TranNetMemberCode", reqVO.getTranNetMemberCode());

        //保留域
        jsonObject.put("ReservedMsg", "查询成功");

        JzbResponse response = jzbClient.send(jsonObject, "KFEJZB6037", "/V1.0/QueryCustAcctId");
        log.info("KFEJZB6037(根据会员代码查询会员子账号)调用返回：{}", response.getData());
        if (response.isSuccess()) {
            return success(response);
        }
        return error(ErrorCodeConstants.QUERY_CUST_ACCTID_ERR, response);
    }

    @PostMapping("/queryCustAcctIdBalance")
    @ApiOperation(value = "查询会员子账号余额")
    @PreAuthenticated
    public CommonResult<JzbResponse> queryCustAcctIdBalance(@RequestBody QueryCustAcctIdBalanceReqVO reqVO) {
        JSONObject jsonObject = new JSONObject();

        //子账户账号
        jsonObject.put("SubAcctNo", reqVO.getSubAcctNo());

        //保留域
        jsonObject.put("ReservedMsg", "查询成功");

        JzbResponse response = jzbClient.send(jsonObject, "KFEJZB6093", "/V1.0/QueryCustAcctIdBalance");
        log.info("KFEJZB6093(查询会员子账号余额)调用返回：{}", response.getData());
        if (response.isSuccess()) {
            return success(response);
        }
        return error(ErrorCodeConstants.QUERY_CUST_ACCTID_BALANCE_ERR, response);
    }


    @PostMapping("/smallAmountTransferQuery")
    @ApiOperation(value = "查询小额鉴权转账结果")
    @PreAuthenticated
    public CommonResult<JzbResponse> smallAmountTransferQuery(@RequestBody SmallAmountTransferQueryReqVO reqVO) {
        JSONObject jsonObject = new JSONObject();

        //原交易流水号:小额鉴权交易请求时的CnsmrSeqNo值
        jsonObject.put("OldTranSeqNo", reqVO.getOldTranSeqNo());
        //交易日期:格式：20181201
        jsonObject.put("TranDate", reqVO.getTranDate());

        //保留域
        jsonObject.put("ReservedMsg", "查询成功");

        JzbResponse response = jzbClient.send(jsonObject, "KFEJZB6061", "/V1.0/SmallAmountTransferQuery");
        log.info("KFEJZB6061(查询小额鉴权转账结果)调用返回：{}", response.getData());
        if (response.isSuccess()) {
            return success(response);
        }
        return error(ErrorCodeConstants.SMALL_AMOUNT_TRANSFER_QUERY_ERR, response);
    }


    @PostMapping("/bankWithdrawCashBackQuery")
    @ApiOperation(value = "查询小额鉴权转账结果,时间间隔不能大于7天")
    @PreAuthenticated
    public CommonResult<JzbResponse> bankWithdrawCashBackQuery(@RequestBody BankWithdrawCashBackQueryReqVO reqVO) {
        JSONObject jsonObject = new JSONObject();

        //功能标识: 1-提现退票 2-小额鉴权退票
        jsonObject.put("FunctionFlag", reqVO.getFunctionFlag());
        //开始时间:格式：20181201
        jsonObject.put("StartDate", reqVO.getStartDate());
        //结束时间:格式：20181201
        jsonObject.put("EndDate", reqVO.getEndDate());

        //保留域
        jsonObject.put("ReservedMsg", "查询成功");

        JzbResponse response = jzbClient.send(jsonObject, "KFEJZB6048", "/V1.0/BankWithdrawCashBackQuery");
        log.info("KFEJZB6048(查询小额鉴权转账结果,时间间隔不能大于7天)调用返回：{}", response.getData());
        if (response.isSuccess()) {
            return success(response);
        }
        return error(ErrorCodeConstants.BANK_WITH_DRAW_CASH_BACK_QUERY_ERR, response);
    }

    @PostMapping("/bankClearQuery")
    @ApiOperation(value = "查询银行在途清算结果,时间间隔不能大于7天")
    @PreAuthenticated
    public CommonResult<JzbResponse> bankClearQuery(@RequestBody BankClearQueryReqVO reqVO) {
        JSONObject jsonObject = new JSONObject();

        //功能标识: 1:全部 2：指定时间段
        jsonObject.put("FunctionFlag", reqVO.getFunctionFlag());
        //开始时间:格式：20181201
        jsonObject.put("StartDate", reqVO.getStartDate());
        //结束时间:格式：20181201
        jsonObject.put("EndDate", reqVO.getEndDate());
        //页码:起始值为1，每次最多返回20条记录，第二页返回的记录数为第21至40条记录，第三页为41至60条记录，顺序均按照建立时间的先后
        jsonObject.put("PageNum", reqVO.getPageNum());

        //保留域
        jsonObject.put("ReservedMsg", "查询成功");

        JzbResponse response = jzbClient.send(jsonObject, "KFEJZB6108", "/V1.0/BankClearQuery");
        log.info("KFEJZB6108(查询银行在途清算结果,时间间隔不能大于7天)调用返回：{}", response.getData());
        if (response.isSuccess()) {
            return success(response);
        }
        return error(ErrorCodeConstants.BANK_CLEAR_QUERY_ERR, response);
    }


    @PostMapping("/subAccountQuest")
    @ApiOperation(value = "分账: 按订单号将某一商户的冻结金额分账给其他一个或多个商户，分账时分账金额分给自己(原充值订单的子账号)的金额默认大于70%（分账后的金额变为可提现金额）")
    @PreAuthenticated
    public CommonResult<JzbResponse> subAccountQuest(SubAccountQuestReqVO reqVO){
        log.info("[subAccountQuest]{}", reqVO);
        JSONObject jsonObject = new JSONObject();

        //原支付订单的子单号
        jsonObject.put("OldPaySubOrderNo", reqVO.getOldPaySubOrderNo());
        //原支付订单所属日期
        jsonObject.put("OldPayOrderDate", reqVO.getOldPayOrderDate());
        //分账转出子账户
        jsonObject.put("OutSubAcctNo", reqVO.getOutSubAcctNo());
        //总交易金额
        jsonObject.put("TranTotalAmt", reqVO.getTranTotalAmt());
        //订单数量 1到30
        jsonObject.put("OrdersCount", reqVO.getOrdersCount());

        jsonObject.put("TranItemArray", reqVO.getTranItemArray());
        //保留域1
        jsonObject.put("ReservedMsgOne", reqVO.getReservedMsgOne());
        //保留域2
        jsonObject.put("ReservedMsgTwo", reqVO.getReservedMsgTwo());

        String seq = jzbClient.getCnsmrSeqNo();
        log.info("[subAccountQuest]OldPaySubOrderNo={}, seq={}", reqVO.getOldPaySubOrderNo(), seq);
        JzbResponse response = jzbClient.send(jsonObject, "KFEJZB6271", "/V1.0/SubAccountQuest", seq);
        log.info("[subAccountQuest]response={}", response);
        if (response.isSuccess()) {
            return success(response);
        }

        return error(ErrorCodeConstants.SUB_ACCOUNT_QUEST_ERR, response);
    }

    @PostMapping("/traFinalStatusQuery")
    @ApiOperation(value = "交易终态查询")
    @PreAuthenticated
    public CommonResult<JzbResponse> traFinalStatusQuery(@RequestBody TraFinalStatusQueryReqVO reqVO){
        log.info("[traFinalStatusQuery]{}", reqVO);
        log.info("[traFinalStatusQuery]mrchCode={}",jzbClient.getJzbProperties().getMrchCode());
        JSONObject jsonObject = new JSONObject();
        //原第三方流水号和原见证受理流水号必输其一
        //原第三方流水号
        jsonObject.put("OldThirdSeqNo", reqVO.getOldThirdSeqNo());
        //原见证受理流水号
        jsonObject.put("OldJzbAcceptSeqNo", reqVO.getOldJzbAcceptSeqNo());
        String seq = jzbClient.getCnsmrSeqNo();
        JzbResponse response = jzbClient.send(jsonObject, "KFEJZB6273", "/V1.0/TraFinalStatusQuery", seq);
        log.info("[traFinalStatusQuery]response={}", response);
        if (response.isSuccess()) {
            return success(response);
        }

        return error(ErrorCodeConstants.TRA_FINAL_STATUS_QUERY, response);
    }

    @PostMapping("/queryCrowdAcountMsg")
    @ApiOperation(value = "订单冻结余额查询")
    @PreAuthenticated
    public CommonResult<JzbResponse> queryCrowdAcountMsg(@RequestBody QueryCrowdAcountMsgReqVO reqVO){
        log.info("[queryCrowdAcountMsg]{}", reqVO);
        JSONObject jsonObject = new JSONObject();
        //原支付场景生成的业务订单号
        jsonObject.put("OldPayBussOrderNo", reqVO.getOldPayBussOrderNo());
        //保留域1
        jsonObject.put("reservedMsgOne", reqVO.getReservedMsgOne());
        //保留域2
        jsonObject.put("ReservedMsgTwo", reqVO.getReservedMsgTwo());
        String seq = jzbClient.getCnsmrSeqNo();
        JzbResponse response = jzbClient.send(jsonObject, "KFEJZB6292", "/V1.0/QueryCrowdAcountMsg", seq);
        log.info("[queryCrowdAcountMsg]response={}", response);
        if (response.isSuccess()) {
            return success(response);
        }
        return error(ErrorCodeConstants.QUERY_CROWD_ACOUNT_MSG_ERR, response);
    }

    @PostMapping("/createDivide")
    @ApiOperation(value = "创建分账任务")
    @PreAuthenticated
    public CommonResult<JzbResponse> createDivide(@RequestBody @Validated OrderQueryReqVO reqVO) {
        log.info("[createDivide]{}", reqVO);
        JzbResponse divideTask = jzbOrderService.createDivideTask(reqVO);
        log.info("[createDivide]创建分账任务成功");
        // 创建分账任务，T+2天执行
        return success(divideTask);
    }


    @PostMapping("/refund")
    @ApiOperation(value = "退款")
    @PermitAll
    public CommonResult<JzbResponse> refund(HttpServletRequest request, @RequestBody @Validated PayRefundCreateReqDTO reqVO) {
        String sign = request.getParameter("sign");
        String secret = stringRedisTemplate.opsForValue().get(PAY_APP_SECRET + reqVO.getAppId());
        if (!StringUtils.hasLength(secret)){
            PayAppDO app = appService.getApp(reqVO.getAppId());
            secret = app.getSecret();
            stringRedisTemplate.opsForValue().set(PAY_APP_SECRET + app.getId(), secret);
        }
        // 校验参数签名
        if (!SignUtils.signDebug(reqVO, secret).equals(sign)){
            PayCommonResult.error(ErrorCodeConstants.PAY_ORDER_ERROR_SIGN);
        }
        // 发起退款
        return success(jzbOrderService.jzbRefund(reqVO));
    }


    @PostMapping("/createDrawCash")
    @ApiOperation(value = "提现")
    @PreAuthenticated
    public CommonResult<JzbResponse> createDrawCash(@Validated @RequestBody JzbDrawCashReqVO createReqVO) {
        // 立马提现
        return success(payDrawCashService.doDrawCash(createReqVO));
    }

    @PostMapping("/signing")
    @ApiOperation(value = "签约协议")
    @PreAuthenticated
    public CommonResult<JzbResponse> signing(@Validated @RequestBody SigningReqVO createReqVO) {
        return success(payDrawCashService.signAgreement(createReqVO));
    }

    @GetMapping("/getPayFund")
    @ApiOperation(value = "获取资金账户信息")
    @PreAuthenticated
    public CommonResult<PayFundRespVO> getPayFund(BigInteger merchantId, String appUserId) {
        log.info("[getPayFund]params: {},{}", merchantId, appUserId);
        TenantContextHolder.setIgnore(true);
        PayFundDO fund = payFundService.getFund(merchantId, appUserId);
        TenantContextHolder.setIgnore(false);
        log.info("[getPayFund] {}", fund);
        return success(PayFundConvert.INSTANCE.convert(fund));
    }

    @GetMapping("/getPayCard")
    @ApiOperation(value = "获取开户信息")
    @PreAuthenticated
    public CommonResult<PayCardRespDTO> getPayCard(String globalId,String companyName,String mobile) {
        PayCardRespDTO cardInfo = payCardService.getValidateCardInfo(globalId,companyName,mobile);
        return success(cardInfo);
    }

    @GetMapping("/getFundDetailsPage")
    @ApiOperation("获取用户资金收支明细分页")
    public CommonResult<PageResult<PayFundDetailsRespVO>> getFundDetailsPage(@Valid PayFundDetailsPageReqVO pageVO) {
        PageResult<PayFundDetailsDO> pageResult = fundDetailsService.getFundDetailsPage(pageVO);
        return success(PayFundDetailsConvert.INSTANCE.convertPage(pageResult));
    }

    @PostMapping("/getPayBank")
    @ApiOperation(value = "获取银行卡信息")
    @PreAuthenticated
    public CommonResult<PayBankRespApiVO> getPayBank(@RequestBody QueryFundBankReqVO reqVO) {
        PayBankRespApiVO bank = payBankService.getBankByAppUserId(reqVO.getMerchantId(), reqVO.getAppUserId(), 1);
        return success(bank);
    }

    @PostMapping("/getPayJzbRate")
    @ApiOperation(value = "获取提现费率")
    @PreAuthenticated
    public CommonResult<PayJzbRateRespVO> getJzbRate(@RequestBody QueryPayJzbRateReqVO reqVO){
        PayJzbRateDO payJzbRateDO = payJzbRateService.selectByDicData(1, reqVO.getMerchantId(), reqVO.getAppUserId());
        if (payJzbRateDO != null){
            return success(PayJzbRateConvert.INSTANCE.convert(payJzbRateDO));
        }
        payJzbRateDO = payJzbRateService.selectDefault(reqVO.getMerchantId());
        return success(PayJzbRateConvert.INSTANCE.convert(payJzbRateDO));
    }

}
